
package com.forestar.mapControl.utils.mapConvert.geometry;


import com.forestar.mapControl.utils.mapConvert.geometry.coordinatesystem.CoordinateSystem;

public class Envelope {
    private double xMin;
    private double xMax;
    private double yMin;
    private double yMax;
    private boolean isEmpty = true;
    private CoordinateSystem coordSystem;

    public Envelope(CoordinateSystem coordSystem)
    {
        this.coordSystem = coordSystem;
        isEmpty = true;
    }

    public Envelope(CoordinateSystem coordSystem, double xMin, double xMax, double yMin, double yMax)
    {
        this.coordSystem = coordSystem;

        this.xMin = xMin;
        this.xMax = xMax;
        this.yMin = yMin;
        this.yMax = yMax;

        this.coordSystem.limitExtent(this);

        isEmpty = false;
    }

    public double getXMin()
    {
        return xMin;
    }

    public double getXMax()
    {
        return xMax;
    }

    public double getYMax()
    {
        return yMax;
    }

    public double getYMin()
    {
        return yMin;
    }

    public void setXMin(double xMin)
        {
            this.xMin = xMin;
        }

    public void setXMax(double xMax)
        {
            this.xMax = xMax;
        }

    public void setYMax(double yMax)
        {
            this.yMax = yMax;
        }

    public void setYMin(double yMin)
        {
            this.yMin = yMin;
        }

    
    public GeoPoint getCentrePoint()
    {
    	double x = (xMin + xMax)/2;
    	double y = (yMin + yMax)/2;
    	return new GeoPoint(coordSystem, x, y);
    }

    @Override
    public String toString()
    {
        return "[" + xMin + "," + xMax + "],[" + yMin + ","
                + yMax + "]";
    }

    public CoordinateSystem getCoordinateSystem()
    {
        return coordSystem;
    }

    public void setCoordSystem(CoordinateSystem coordSystem)
      {
        this.coordSystem = coordSystem;
      }

    public void extend(double x, double y)
    {
        if (isEmpty)
        {
            this.xMin = x;
            this.xMax = x;
            this.yMin = y;
            this.yMax = y;
            isEmpty = false;
        }
        expandToInclude(x, y);
    }

    public void expandToInclude(double x, double y)
        {
            this.xMin = x < xMin ? x : xMin;
            this.xMax = x > xMax ? x : xMax;
            this.yMin = y < yMin ? y : yMin;
            this.yMax = y > yMax ? y : yMax;
        }

    public boolean intersect(Envelope envelope)
    {
        Envelope projected;
        if (this.coordSystem.equals(envelope.getCoordinateSystem()))
        {
            projected = envelope;
        }
        else
        {
            projected = CoordinateSystem.transform(envelope.getCoordinateSystem(), this.coordSystem, envelope);
        }

        if (isEmpty || projected.isEmpty) { return false; }
        return !(projected.xMin > xMax ||
            projected.xMax < xMin ||
            projected.yMin > yMax ||
            projected.yMax < yMin);
    }

    public boolean contain(double x, double y)
        {
            return (x >= xMin && x <= xMax && y >= yMin && y <= yMax);
        }
}
